/*
 * Created on Feb 15, 2005
 * Created by dfhuynh
 */
package it.okkam.longwell.ui.command;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.apache.velocity.VelocityContext;

import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.impl.PropertyImpl;
import com.hp.hpl.jena.tdb.TDBFactory;
import com.hp.hpl.jena.util.FileManager;
import com.hp.hpl.jena.vocabulary.DC;

import de.fuberlin.wiwiss.ng4j.NamedGraphModel;
import de.fuberlin.wiwiss.ng4j.NamedGraphSet;
import de.fuberlin.wiwiss.ng4j.impl.NamedGraphSetImpl;

import edu.mit.simile.longwell.LongwellServer;
import edu.mit.simile.longwell.LongwellServlet;
import edu.mit.simile.longwell.schema.IStructuredSchema;
import edu.mit.simile.longwell.ui.Facade;
import edu.mit.simile.longwell.ui.FlairMessage;
import edu.mit.simile.longwell.ui.FlairStructuredModel;
import edu.mit.simile.longwell.ui.InjectionManager;
import edu.mit.simile.longwell.ui.command.CommandBase;

/**
 * @author dfhuynh
 */
public class GraphsListAdministrationCommand extends CommandBase {
	final static private Logger s_logger = Logger
			.getLogger(GraphsListAdministrationCommand.class);
	static HashMap<String, HashMap<String, Dataset>> hash = new HashMap<String, HashMap<String, Dataset>>();
	final protected String m_template;
	private String datasetSelected;
	private File[] m_filesComuni;
	public ArrayList<String> graphsFromDataset;

	/**
	 * @param injectionManager
	 */
	public GraphsListAdministrationCommand(InjectionManager injectionManager,
			String template) {
		super(injectionManager);
		m_template = template;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * edu.mit.simile.flair.IFlairCommand#execute(edu.mit.simile.flair.FlairMessage
	 * )
	 */
	public void execute(FlairMessage msg) throws ServletException {
		datasetSelected = msg.m_request.getParameterValues("comuneName")[0];

		try {
			VelocityContext vcContext = createContext(msg);
			HttpSession session = msg.m_request.getSession();
			String sessionId = session.getId();
			// vcContext.put("graphs", getGraphs(msg,(String[])
			// session.getAttribute(sessionId)));
			// vcContext.put("graphs", getGraphsFromModel(msg,listaComuni));
			vcContext.put("graphs", getGraphsFromDataset(msg, datasetSelected));
			vcContext.put("sessionId", msg.m_request.getSession().getId());
			Model contextModel = getContextModel();
			for (int i = 0; i < graphsFromDataset.size(); i++) {
				getGraphInfo(graphsFromDataset.get(i),contextModel);
			}

			msg.m_ve.mergeTemplate(m_template, vcContext,
					msg.m_response.getWriter());
		} catch (Exception e) {
			s_logger.error(e);
			e.printStackTrace();
		}
	}

	// metodo che restituisce la lista dei grafi presenti in un certo dataset.
	protected ArrayList getGraphsFromDataset(FlairMessage msg,
			String datasetName) {
		graphsFromDataset = new ArrayList<String>();
		File file = new File(datasetName + "-assembler.ttl");
		String assemblerFile = file.getName();
		s_logger.info("Loading assembler : "
				+ LongwellServlet.getAssemblerDirectory() + "/" + assemblerFile);
		Dataset ds = TDBFactory.assembleDataset(LongwellServlet
				.getAssemblerDirectory() + "/" + assemblerFile);

		Iterator<String> graphNames = ds.listNames();
		if (graphNames != null) {
			while (graphNames.hasNext()) {
				String graphName = graphNames.next();
				// System.out.println(graphName);
				graphsFromDataset.add(graphName);
			}
		}
		return graphsFromDataset;
	}

	private Model getContextModel() {
		String filename = "/tmp/Folgaria-Context.trig";
		NamedGraphSet graphSet = new NamedGraphSetImpl();
		NamedGraphModel ngModel = new NamedGraphModel(graphSet, "");
		InputStream in = FileManager.get().open(filename);
		if (in == null) {
			System.out.println("File: " + filename + " not found");
		}
		graphSet.read(in, "TRIG", "");
		try {
			ngModel.write(new PrintWriter(new File(filename)), "TRIG");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		try {
			in.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return ngModel;
	}

	/**
	 * metodo che dato un namedGraph si occupa di trovare le informazioni di
	 * contesto
	 * 
	 * @param namedGraph
	 * @return <namedGraph,<isPartOf,xxxxxxxxxx> <title,yyyyyyyyyyy>
	 *         <issued,dd/mm/yyyy>>
	 */
	protected HashMap<String, HashMap<String, String>> getGraphInfo(
			String namedGraph, Model contextModel) {
		HashMap<String, HashMap<String, String>> graphInfos = new HashMap<String, HashMap<String, String>>();

		// lettura del grafo di contesto dal
		// dataset------------------------------------------------------------
		// Model contextModel=null;
		// File file = new File(datasetSelected+"-assembler.ttl");
		// String assemblerFile = file.getName() ;
		// Dataset ds =
		// TDBFactory.assembleDataset(LongwellServlet.getAssemblerDirectory()+"/"+assemblerFile);
		// contextModel =
		// ds.getNamedModel("http://www.provincia.tn.it/bcc/resource/"+datasetSelected);
		// -----------------------------------------------------------------------------------------------------


		Iterator<Statement> statements = contextModel.listStatements(null,
				DC.title, (RDFNode) null);
		// for each flow (anagrafe, catasto, titolarita)
		while (statements.hasNext()) {

			HashMap<String, String> graphsWithLabel = new HashMap<String, String>();
			Statement statement = statements.next();
			String titleFlow = statement.getObject().toString();

			Resource uriFlow = statement.getSubject();
			Property hasPart = new PropertyImpl(
					"http://purl.org/dc/elements/1.1/hasPart");
			Iterator<Statement> graphs = contextModel.listStatements(uriFlow,
					hasPart, (RDFNode) null);
			// for each graph
			while (graphs.hasNext()) {
				Statement graph = graphs.next();
				Property issued = new PropertyImpl(
						"http://purl.org/dc/elements/1.1/issued");
				Property title = new PropertyImpl(
						"http://purl.org/dc/elements/1.1/title");
				Resource graphName = (Resource) graph.getObject();
				Iterator<Statement> graphLabel = contextModel.listStatements(
						graphName, issued, (RDFNode) null);
				// read label
				while (graphLabel.hasNext()) {
					String labelIssued = graphLabel.next().getObject()
							.toString();
					// String titleGraph =
					// defaultModel.listStatements(graphLabel.next().getSubject(),
					// title, (RDFNode)null).next().getObject().toString();
					graphsWithLabel.put(graphName.toString(), labelIssued);
				}
			}
			graphInfos.put(titleFlow, graphsWithLabel);
		}
		/*
		 * Iterator<String> graphNames = ds.listNames(); if(graphNames!=null){
		 * while (graphNames.hasNext()) { String graphName = graphNames.next();
		 * } }
		 */
		return graphInfos;
	}

	static public HashMap<String, Dataset> getGraphsByDataset(String sessionId) {
		return hash.get(sessionId);
	}
}
